import requestIp from 'request-ip';
import { SystemUserDecoratorType } from 'src/decorator/operuser.decorator';
import { OperType, Role } from 'src/global-type';
import { SystemUserDocument } from 'src/system-user/schemas/system-user.schema';
import { CreateSystemLogType } from './system-log.interface';

export const getIp = (req): string => {
  const temp = typeof req === 'string' ? req : requestIp.getClientIp(req);
  
  const IPADDRESS_REG =
    /((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))/;
  const ipAdd = IPADDRESS_REG.exec(temp);
  return ipAdd ? ipAdd[0] : '127.0.0.1';
};

export interface TargetInfoType {
  targetType: TargetType;
  target: string;
  oldData?: string;
  newData?: string;
}

interface OperInfoType {
  userId: string;
  account: string;
  userName: string;
  ownerId: string;
  ip: string;
}

const mapOperType = {
  create: '添加',
  delete: '删除',
  modify: '修改',
  query: '查询',
  login: '登录',
  logout: '登出',
  import: '导入',
  export: '导出',
};

export enum TargetType {
  commonInfoPlatform = '公共信息平台',
  systemUser = '系统用户',
  systemLog = '系统日志',
  iotSim = '流量卡',
  webNav = '网址导航',
  systemWarningRule = '系统告警规则',
  systemWarningHistory = '系统告警历史记录',
  dingRobot = '钉钉机器人',
}

export const getOperInfo = (
  user: SystemUserDecoratorType | SystemUserDocument,
  req?,
): OperInfoType => {
  const ip = req ? getIp(req) : (user as SystemUserDecoratorType)?.ip;
  return {
    userId: user._id || user.id,
    account: user.account,
    userName: user.userName,
    ownerId: user.role !== Role.ADMIN ? user.ownerId : '',
    ip,
  };
};

export const buildSysRecordData = (
  operInfo: OperInfoType,
  operType: OperType,
  targetInfo: TargetInfoType,
  appendix = '', // 附加信息
): CreateSystemLogType => {
  return {
    userId: operInfo.userId,
    account: operInfo.account,
    userName: operInfo.userName,
    ownerId: operInfo.ownerId,
    ip: operInfo?.ip,
    operType,
    targetType: targetInfo.targetType,
    target: targetInfo.target,
    oldData: targetInfo.oldData,
    newData: targetInfo.newData,
    operTime: new Date(),
    description: `${operInfo.userName}(${operInfo.account}) ${mapOperType[operType]}了 ${targetInfo.targetType} ${targetInfo.target} ${appendix}。`,
  };
};
